package com.opticon.vaadinR.tools.density;

import com.google.common.io.Files;
import com.opticon.vaadinR.core.RFilter;
import com.opticon.vaadinR.core.RSource;
import com.opticon.vaadinR.core.conf.CoreConfiguration;
import com.opticon.vaadinR.core.constants.RConstants;
import com.opticon.vaadinR.exceptions.RVaadinException;
import com.opticon.vaadinR.interfaces.RResultHandler;
import com.opticon.vaadinR.runnable.RExecution;
import com.opticon.vaadinR.runnable.RRunner;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;

/**
 * This class is a
 */
public class HuberExecution extends RExecution {
    private static Logger logger = Logger.getLogger(HuberExecution.class);

    private static final String DEFAULT = "NA";
    private static final String RSCRIPT_NAME = "huber";

    private static final String RSCRIPT_PARAM_INPUT_FILE = "file";
    private static final String RSCRIPT_PARAM_PVALUE = "pvalue";

    protected String iFileName = DEFAULT;
    protected String iSessionID = DEFAULT;
    protected String iPValue = DEFAULT;

    protected RResultHandler iRResultHandler = null;

    public HuberExecution(RResultHandler aRResultHandler) {
        iRResultHandler = aRResultHandler;
    }

    @Override
    public void run() {

        if (proceed()) {
            try {
                File lFile = new File(CoreConfiguration.getRScript(RSCRIPT_NAME));
                iRSource = new RSource(lFile);

                iRFilter = new RFilter();
                iRFilter.add(RSCRIPT_PARAM_INPUT_FILE, iFileName);
                iRFilter.add(RSCRIPT_PARAM_PVALUE, iPValue);

                iRFilter.add(RConstants.WORKSPACE, CoreConfiguration.getTmpDir().getCanonicalPath());
                long lTastMillis = System.currentTimeMillis();
                iRFilter.add(RConstants.TASKID, "" + lTastMillis);
                iRFilter.add(RConstants.SESSIONID, iSessionID);
                iRSource.filter(iRFilter);

                // Dump the filtered script.
                Files.write(iRSource.getCode().getBytes(), new File(CoreConfiguration.getTmpDir().getCanonicalPath(), "" + lTastMillis + "_script.R"));

                logger.debug("starting R");
                iRRunner = new RRunner(iRSource);
                iRRunner.run();

                logger.debug("loading results");
                iRResultHandler.loadRResults(iRFilter);

                iObservable.setChanged();
                notifyObservers();

                logger.debug("processing results");


            } catch (IOException e) {
                throw new RVaadinException(e);
            }
        }

    }

    private boolean proceed() {
        // Check if file exists.
        if(iFileName.equals(DEFAULT)){
            logger.debug("input filename has not been set");
            return false;
        }

        File lFile = new File(iFileName);

        if(lFile.exists() == false){
            logger.debug("input file does not exist");
            return false;
        }

        if(iPValue.equals(DEFAULT)){
            logger.debug("pvalue has not been set");
            return false;
        }

        try {
            Double.parseDouble(iPValue);
        } catch (NumberFormatException e) {
            logger.debug("pvalue is not a number");
            return false;
        }

        return true;
    }

    public void setPValue(String aPValue) {
        iPValue = aPValue;
    }

    public void setFileName(String aFileName) {
        iFileName = aFileName;
    }

    public void setSessionID(String aSessionID) {
        iSessionID = aSessionID;
    }

}
